{
  "name": "Case 48: Tender Compliance Matrix Builder",
  "nodes": [
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "173kJrrZpP8JGhAXBKRuXIDVzHzAY8xf2",
          "mode": "list",
          "cachedResultName": "Case 48 - Tender Folder",
          "cachedResultUrl": "https://drive.google.com/drive/folders/173kJrrZpP8JGhAXBKRuXIDVzHzAY8xf2"
        },
        "event": "fileCreated",
        "options": {}
      },
      "id": "0f269e0d-42a2-4873-978b-eacb42e71b9e",
      "name": "Monitor RFP Upload Folder",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        -1152,
        -32
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "Cf6MNES8JrQntp3r",
          "name": "Google Drive account"
        }
      }
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $json.id }}",
          "mode": "id"
        },
        "options": {}
      },
      "id": "e2229e89-3edb-4af6-bcb9-bebade24f412",
      "name": "Download RFP Document",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -992,
        -32
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "Cf6MNES8JrQntp3r",
          "name": "Google Drive account"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.cloud.llamaindex.ai/api/v1/parsing/upload",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer llx-7BWYrvPwfUhgdXbZMtaNCsr2O0h7JH4dkHjHisxcvq46bkIj"
            }
          ]
        },
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formBinaryData",
              "name": "file",
              "inputDataFieldName": "data"
            }
          ]
        },
        "options": {}
      },
      "id": "5f8cfea9-e0bf-4e08-aa99-81a0e74277ba",
      "name": "Upload to Parser",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -800,
        -32
      ]
    },
    {
      "parameters": {
        "amount": 20
      },
      "id": "aec7a756-84b4-4251-b34b-cc70cb8e9ca0",
      "name": "Wait for Parsing",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        -576,
        -32
      ],
      "webhookId": "b2fbbeb9-1ecb-4d94-9f1b-9dcb54bbfc32"
    },
    {
      "parameters": {
        "url": "=https://api.cloud.llamaindex.ai/api/v1/parsing/job/{{ $node[\"Upload to Parser\"].json[\"id\"] }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer llx-7BWYrvPwfUhgdXbZMtaNCsr2O0h7JH4dkHjHisxcvq46bkIj"
            }
          ]
        },
        "options": {}
      },
      "id": "5dac2819-9bc0-4c4f-8222-cfb87729a846",
      "name": "Check Parsing Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -400,
        -32
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "conditions": [
                  {
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "SUCCESS",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "SUCCESS"
            },
            {
              "conditions": {
                "conditions": [
                  {
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "PENDING",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "PENDING"
            }
          ]
        },
        "options": {}
      },
      "id": "223f82c1-f373-4774-81f4-496bf4fbd237",
      "name": "Route Based on Status",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        -224,
        -32
      ]
    },
    {
      "parameters": {
        "url": "=https://api.cloud.llamaindex.ai/api/v1/parsing/job/{{ $node[\"Upload to Parser\"].json[\"id\"] }}/result/markdown",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer llx-7BWYrvPwfUhgdXbZMtaNCsr2O0h7JH4dkHjHisxcvq46bkIj"
            }
          ]
        },
        "options": {}
      },
      "id": "9c761546-e687-4257-b2eb-24cabb2d0a72",
      "name": "Extract Parsed Content",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -96,
        -304
      ]
    },
    {
      "parameters": {
        "jsCode": "const markdown = $input.first().json.markdown;\n\n// Split by requirement sections - look for numbered requirements or bullet points\nconst requirementSections = [];\n\n// Try multiple patterns for requirement splitting\nconst patterns = [\n  /\\n#+\\s*Requirement\\s+\\d+/gi,\n  /\\n\\d+\\.\\s+/g,\n  /\\n-\\s+\\*\\*Requirement/gi,\n  /\\n\\*\\s+\\*\\*[A-Z]/g\n];\n\nlet sections = [];\nlet patternUsed = null;\n\n// Try each pattern until we find one that splits the document\nfor (const pattern of patterns) {\n  const testSections = markdown.split(pattern);\n  if (testSections.length > 2) {\n    sections = testSections;\n    patternUsed = pattern;\n    break;\n  }\n}\n\n// If no pattern worked, try to find requirement keywords and split manually\nif (sections.length <= 2) {\n  const lines = markdown.split('\\n');\n  let currentSection = '';\n  \n  for (const line of lines) {\n    const lowerLine = line.toLowerCase();\n    if (lowerLine.includes('requirement') || \n        lowerLine.includes('mandatory') ||\n        lowerLine.match(/^\\d+\\./) ||\n        lowerLine.match(/^[a-z]\\)/i)) {\n      if (currentSection.trim().length > 50) {\n        requirementSections.push({\n          json: {\n            requirement_text: currentSection.trim(),\n            requirement_number: requirementSections.length + 1\n          }\n        });\n      }\n      currentSection = line;\n    } else {\n      currentSection += '\\n' + line;\n    }\n  }\n  \n  // Add last section\n  if (currentSection.trim().length > 50) {\n    requirementSections.push({\n      json: {\n        requirement_text: currentSection.trim(),\n        requirement_number: requirementSections.length + 1\n      }\n    });\n  }\n} else {\n  // Process sections from pattern split\n  for (let i = 1; i < sections.length; i++) {\n    const section = sections[i].trim();\n    if (section.length > 30) {\n      requirementSections.push({\n        json: {\n          requirement_text: section,\n          requirement_number: i\n        }\n      });\n    }\n  }\n}\n\n// If still no sections found, return entire document as single requirement\nif (requirementSections.length === 0) {\n  return [{\n    json: {\n      requirement_text: markdown,\n      requirement_number: 1\n    }\n  }];\n}\n\nreturn requirementSections;"
      },
      "id": "cb71b131-2dcf-4bd7-9bbe-047f5ee6d8b4",
      "name": "Requirement Splitter",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        96,
        -304
      ]
    },
    {
      "parameters": {
        "text": "={{ $json.requirement_text }}",
        "attributes": {
          "attributes": [
            {
              "name": "Requirement_ID",
              "description": "The requirement ID or number (e.g., REQ-001, 3.2.1)"
            },
            {
              "name": "Requirement_Description",
              "description": "The full text description of the requirement"
            },
            {
              "name": "Requirement_Type",
              "description": "Whether this is Mandatory, Optional, or Desirable"
            },
            {
              "name": "Category",
              "description": "Category like Technical, Functional, Compliance, Security, Documentation"
            },
            {
              "name": "Acceptance_Criteria",
              "description": "Any specific acceptance or verification criteria mentioned"
            }
          ]
        },
        "options": {}
      },
      "id": "45798eec-abcd-4405-ba34-afa761eb2391",
      "name": "AI Requirement Extractor",
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "typeVersion": 1.2,
      "position": [
        272,
        -304
      ]
    },
    {
      "parameters": {
        "jsCode": "// Process EACH item separately and return array of results\nconst items = [];\n\nfor (const item of $input.all()) {\n  const reqData = item.json.output;\n\n  // EMBEDDED PRODUCT SPECIFICATIONS DATABASE\n  const productSpecs = {\n    // Cloud & Infrastructure\n    \"cloud_deployment\": true,\n    \"cloud_native\": true,\n    \"aws_compatible\": true,\n    \"azure_compatible\": true,\n    \"gcp_compatible\": false,\n    \"on_premise_deployment\": false,\n    \"hybrid_cloud\": true,\n    \"multi_cloud\": false,\n    \n    // Architecture\n    \"microservices\": true,\n    \"multi_tenant\": true,\n    \"single_tenant\": false,\n    \"containerized\": true,\n    \"kubernetes\": true,\n    \"docker\": true,\n    \"serverless\": false,\n    \n    // Integration\n    \"rest_api\": true,\n    \"graphql_api\": false,\n    \"soap_api\": false,\n    \"webhook_support\": true,\n    \"api_integration\": true,\n    \"third_party_integration\": true,\n    \"erp_integration\": true,\n    \"crm_integration\": true,\n    \n    // Security & Authentication\n    \"sso_support\": true,\n    \"saml\": true,\n    \"oauth2\": true,\n    \"ldap\": true,\n    \"active_directory\": true,\n    \"mfa\": true,\n    \"biometric_auth\": false,\n    \"encryption_at_rest\": true,\n    \"encryption_in_transit\": true,\n    \"role_based_access\": true,\n    \n    // Compliance & Certifications\n    \"gdpr_compliant\": true,\n    \"hipaa_compliant\": false,\n    \"sox_compliant\": true,\n    \"iso27001_certified\": false,\n    \"iso9001_certified\": true,\n    \"pci_dss_compliant\": false,\n    \n    // Performance & Reliability\n    \"99_9_uptime\": true,\n    \"99_99_uptime\": false,\n    \"auto_scaling\": true,\n    \"load_balancing\": true,\n    \"disaster_recovery\": true,\n    \"backup_restore\": true,\n    \"real_time_processing\": true,\n    \n    // Features\n    \"mobile_app\": false,\n    \"web_app\": true,\n    \"offline_mode\": false,\n    \"reporting\": true,\n    \"analytics\": true,\n    \"dashboard\": true,\n    \"notifications\": true,\n    \"workflow_automation\": true,\n    \n    // Advanced Technologies\n    \"ai_ml_capabilities\": true,\n    \"blockchain\": false,\n    \"iot_support\": false,\n    \"big_data\": true,\n    \"real_time_analytics\": true,\n    \n    // Support & Documentation\n    \"24x7_support\": true,\n    \"technical_documentation\": true,\n    \"api_documentation\": true,\n    \"training_provided\": true,\n    \"onboarding_support\": true\n  };\n\n  // Keyword mapping to product specs\n  const keywordMapping = {\n    \"cloud\": [\"cloud_deployment\", \"cloud_native\"],\n    \"aws\": [\"aws_compatible\"],\n    \"azure\": [\"azure_compatible\"],\n    \"on-premise\": [\"on_premise_deployment\"],\n    \"on premise\": [\"on_premise_deployment\"],\n    \"microservice\": [\"microservices\"],\n    \"multi-tenant\": [\"multi_tenant\"],\n    \"container\": [\"containerized\"],\n    \"kubernetes\": [\"kubernetes\"],\n    \"docker\": [\"docker\"],\n    \"api\": [\"rest_api\", \"api_integration\"],\n    \"rest\": [\"rest_api\"],\n    \"integration\": [\"api_integration\", \"third_party_integration\"],\n    \"sso\": [\"sso_support\"],\n    \"single sign-on\": [\"sso_support\"],\n    \"saml\": [\"saml\"],\n    \"oauth\": [\"oauth2\"],\n    \"ldap\": [\"ldap\"],\n    \"active directory\": [\"active_directory\"],\n    \"mfa\": [\"mfa\"],\n    \"multi-factor\": [\"mfa\"],\n    \"encryption\": [\"encryption_at_rest\", \"encryption_in_transit\"],\n    \"gdpr\": [\"gdpr_compliant\"],\n    \"hipaa\": [\"hipaa_compliant\"],\n    \"iso 27001\": [\"iso27001_certified\"],\n    \"iso27001\": [\"iso27001_certified\"],\n    \"pci dss\": [\"pci_dss_compliant\"],\n    \"uptime\": [\"99_9_uptime\"],\n    \"99.9%\": [\"99_9_uptime\"],\n    \"disaster recovery\": [\"disaster_recovery\"],\n    \"backup\": [\"backup_restore\"],\n    \"mobile\": [\"mobile_app\"],\n    \"mobile app\": [\"mobile_app\"],\n    \"reporting\": [\"reporting\"],\n    \"analytics\": [\"analytics\"],\n    \"dashboard\": [\"dashboard\"],\n    \"ai\": [\"ai_ml_capabilities\"],\n    \"machine learning\": [\"ai_ml_capabilities\"],\n    \"ml\": [\"ai_ml_capabilities\"],\n    \"blockchain\": [\"blockchain\"],\n    \"24x7\": [\"24x7_support\"],\n    \"24/7\": [\"24x7_support\"],\n    \"documentation\": [\"technical_documentation\"]\n  };\n\n  // Extract requirement details\n  const reqId = reqData.Requirement_ID || `REQ-${item.json.requirement_number || 1}`;\n  const reqDescription = (reqData.Requirement_Description || '').trim();\n  const reqType = (reqData.Requirement_Type || 'Mandatory').trim();\n  const category = (reqData.Category || 'General').trim();\n  const acceptanceCriteria = (reqData.Acceptance_Criteria || 'Not specified').trim();\n\n  // Match requirement against product specs\n  const reqTextLower = reqDescription.toLowerCase();\n  const matchedSpecs = [];\n  let capabilityStatus = 'Uncertain';\n  let matchingProductSpec = 'None';\n  let gapDescription = '';\n\n  // Check for keyword matches\n  for (const [keyword, specs] of Object.entries(keywordMapping)) {\n    if (reqTextLower.includes(keyword.toLowerCase())) {\n      for (const spec of specs) {\n        if (productSpecs[spec] !== undefined) {\n          matchedSpecs.push({\n            spec: spec,\n            value: productSpecs[spec],\n            keyword: keyword\n          });\n        }\n      }\n    }\n  }\n\n  // Determine capability status\n  if (matchedSpecs.length > 0) {\n    const allMet = matchedSpecs.every(s => s.value === true);\n    const someMet = matchedSpecs.some(s => s.value === true);\n    \n    if (allMet) {\n      capabilityStatus = 'Met';\n      matchingProductSpec = matchedSpecs.map(s => s.spec).join(', ');\n      gapDescription = 'Requirement fully met by current product capabilities';\n    } else if (someMet) {\n      capabilityStatus = 'Partial';\n      const metSpecs = matchedSpecs.filter(s => s.value).map(s => s.spec);\n      const unmetSpecs = matchedSpecs.filter(s => !s.value).map(s => s.spec);\n      matchingProductSpec = metSpecs.join(', ');\n      gapDescription = `Partially met. Missing: ${unmetSpecs.join(', ')}`;\n    } else {\n      capabilityStatus = 'Unmet';\n      matchingProductSpec = 'Not available';\n      gapDescription = `Required capabilities not currently available: ${matchedSpecs.map(s => s.spec).join(', ')}`;\n    }\n  } else {\n    capabilityStatus = 'Uncertain';\n    matchingProductSpec = 'No direct match found';\n    gapDescription = 'Unable to determine - requires manual review';\n  }\n\n  // Risk assessment\n  let riskLevel = 'Low';\n  if (reqType.toLowerCase().includes('mandatory')) {\n    if (capabilityStatus === 'Unmet') {\n      riskLevel = 'High';\n    } else if (capabilityStatus === 'Partial' || capabilityStatus === 'Uncertain') {\n      riskLevel = 'Medium';\n    } else {\n      riskLevel = 'Low';\n    }\n  } else if (reqType.toLowerCase().includes('desirable')) {\n    if (capabilityStatus === 'Unmet') {\n      riskLevel = 'Medium';\n    } else {\n      riskLevel = 'Low';\n    }\n  } else {\n    riskLevel = 'Low';\n  }\n\n  // Recommended action\n  let recommendedAction = '';\n  let estimatedEffort = 'NA';\n\n  if (capabilityStatus === 'Met') {\n    recommendedAction = 'No action required - Document existing capability';\n    estimatedEffort = 'NA';\n  } else if (capabilityStatus === 'Partial') {\n    recommendedAction = 'Complete missing components - Assess development feasibility';\n    estimatedEffort = 'Medium';\n  } else if (capabilityStatus === 'Unmet' && reqType.toLowerCase().includes('mandatory')) {\n    recommendedAction = 'URGENT: Evaluate build vs buy vs partner solution';\n    estimatedEffort = 'High';\n  } else if (capabilityStatus === 'Unmet') {\n    recommendedAction = 'Consider for product roadmap if strategically important';\n    estimatedEffort = 'Medium';\n  } else {\n    recommendedAction = 'Manual review required - Engage technical team';\n    estimatedEffort = 'Low';\n  }\n\n  items.push({\n    json: {\n      Requirement_ID: reqId,\n      Requirement_Description: reqDescription,\n      Requirement_Type: reqType,\n      Category: category,\n      Acceptance_Criteria: acceptanceCriteria,\n      Our_Capability_Status: capabilityStatus,\n      Matching_Product_Spec: matchingProductSpec,\n      Gap_Description: gapDescription,\n      Risk_Level: riskLevel,\n      Recommended_Action: recommendedAction,\n      Estimated_Effort: estimatedEffort,\n      Keywords_Matched: matchedSpecs.map(s => s.keyword).join(', ') || 'None',\n      Processing_Timestamp: new Date().toISOString()\n    }\n  });\n}\n\nreturn items;"
      },
      "id": "e98b9019-02f0-4636-9027-93153e18cfd0",
      "name": "Compliance Analyzer",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        688,
        -128
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "184NEglt6Y0GcqpvbxERZt0dxrBtEBY0TDtqalTalp4o",
          "mode": "list",
          "cachedResultName": "Case_48_Tender_Compliance_Matrix",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/184NEglt6Y0GcqpvbxERZt0dxrBtEBY0TDtqalTalp4o/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Sheet1",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/184NEglt6Y0GcqpvbxERZt0dxrBtEBY0TDtqalTalp4o/edit#gid=0"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [],
          "schema": [
            {
              "id": "Requirement ID",
              "displayName": "Requirement ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Requirement Description",
              "displayName": "Requirement Description",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor Performance",
              "displayName": "Vendor Performance",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Compliance Status",
              "displayName": "Compliance Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Gap Analysis",
              "displayName": "Gap Analysis",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Remediation Action",
              "displayName": "Remediation Action",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Estimated Cost",
              "displayName": "Estimated Cost",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Priority",
              "displayName": "Priority",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Bid Recommendation",
              "displayName": "Bid Recommendation",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "id": "3255f671-0e73-473f-89ad-960e099f1e32",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        864,
        -128
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "LOs2dbk9lby0NfDM",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const allRequirements = $input.all();\n\n// Calculate compliance metrics\nconst totalRequirements = allRequirements.length;\nconst mandatoryReqs = allRequirements.filter(r => {\n  const reqType = r.json.Requirement_Type || '';\n  return reqType.toLowerCase().includes('mandatory');\n});\nconst totalMandatory = mandatoryReqs.length;\n\nconst metReqs = allRequirements.filter(r => r.json.Our_Capability_Status === 'Met');\nconst unmetReqs = allRequirements.filter(r => r.json.Our_Capability_Status === 'Unmet');\nconst partialReqs = allRequirements.filter(r => r.json.Our_Capability_Status === 'Partial');\nconst uncertainReqs = allRequirements.filter(r => r.json.Our_Capability_Status === 'Uncertain');\n\nconst metMandatory = mandatoryReqs.filter(r => r.json.Our_Capability_Status === 'Met').length;\nconst unmetMandatory = mandatoryReqs.filter(r => r.json.Our_Capability_Status === 'Unmet');\nconst partialMandatory = mandatoryReqs.filter(r => r.json.Our_Capability_Status === 'Partial');\n\nconst compliancePercentage = totalMandatory > 0 \n  ? Math.round((metMandatory / totalMandatory) * 100) \n  : 0;\n\n// High risk items (unmet OR partial OR uncertain mandatory)\nconst highRiskItems = allRequirements\n  .filter(r => {\n    const reqType = r.json.Requirement_Type || '';\n    const status = r.json.Our_Capability_Status || '';\n    return reqType.toLowerCase().includes('mandatory') && \n           (status === 'Unmet' || status === 'Partial' || status === 'Uncertain');\n  })\n  .map(r => {\n    const desc = r.json.Requirement_Description || 'No description';\n    const status = r.json.Our_Capability_Status || 'Unknown';\n    return `• ${r.json.Requirement_ID} [${status}]: ${desc.substring(0, 80)}...`;\n  });\n\n// Build email content\nconst emailSubject = `RFP Compliance Analysis - ${compliancePercentage}% Mandatory Requirements Met`;\n\nconst emailBody = `Dear Bid Manager and Product Team,\n\nA Technical RFP has been analyzed for compliance with our current product capabilities.\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n📊 COMPLIANCE SUMMARY\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nOverall Compliance: ${compliancePercentage}%\nTotal Requirements: ${totalRequirements}\nMandatory Requirements: ${totalMandatory}\n\nMandatory Requirements Status:\n✅ Met: ${metMandatory} (${totalMandatory > 0 ? Math.round((metMandatory/totalMandatory)*100) : 0}%)\n⚠️ Partial: ${partialMandatory.length} (${totalMandatory > 0 ? Math.round((partialMandatory.length/totalMandatory)*100) : 0}%)\n❌ Unmet: ${unmetMandatory.length} (${totalMandatory > 0 ? Math.round((unmetMandatory.length/totalMandatory)*100) : 0}%)\n❓ Uncertain: ${mandatoryReqs.filter(r => r.json.Our_Capability_Status === 'Uncertain').length}\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🚨 HIGH RISK - UNMET MANDATORY REQUIREMENTS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${highRiskItems.length > 0 ? highRiskItems.slice(0, 5).join('\\n') : 'None - All mandatory requirements met!'}\n${highRiskItems.length > 5 ? `\\n... and ${highRiskItems.length - 5} more (see detailed matrix)` : ''}\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n📈 BREAKDOWN BY STATUS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nAll Requirements:\n- Met: ${metReqs.length}\n- Partial: ${partialReqs.length}\n- Unmet: ${unmetReqs.length}\n- Uncertain: ${uncertainReqs.length}\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n✅ RECOMMENDED ACTIONS\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${unmetMandatory.length > 0 ? \n  '1. IMMEDIATE: Schedule bid/no-bid decision meeting\\n2. Evaluate feasibility of developing missing capabilities\\n3. Explore partnership or third-party solutions\\n4. Assess timeline and budget impact\\n5. Consider risk mitigation strategies' \n  : \n  '1. Proceed with bid preparation\\n2. Document all compliant capabilities\\n3. Prepare technical response showcasing strengths\\n4. Address partial/uncertain items with technical team'}\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nDetailed compliance matrix has been logged to Google Sheets.\nReview the complete analysis for all requirements and specific gaps.\n\nProcessed: ${new Date().toISOString()}\n\nThis is an automated analysis from the Tender Compliance System.\n\nBest regards,\nAutomated Compliance Analyzer`;\n\nreturn {\n  json: {\n    email_subject: emailSubject,\n    email_body: emailBody,\n    recipient_emails: 'bid.manager@company.com, product.team@company.com',\n    compliance_percentage: compliancePercentage,\n    total_requirements: totalRequirements,\n    total_mandatory: totalMandatory,\n    met_mandatory: metMandatory,\n    unmet_mandatory_count: unmetMandatory.length,\n    high_risk_count: highRiskItems.length\n  }\n};"
      },
      "id": "bd0dfc53-a0b4-498f-b315-b9546c0fe01b",
      "name": "Generate Email Summary",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1088,
        -128
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $json.recipient_emails }}",
        "subject": "={{ $json.email_subject }}",
        "emailType": "text",
        "message": "={{ $json.email_body }}",
        "options": {}
      },
      "id": "1234120c-feb3-492b-915d-6423fd8cd7ec",
      "name": "Send Email via Gmail",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1312,
        -128
      ],
      "webhookId": "4b9acb34-4295-40dc-b095-7d1208460769",
      "credentials": {
        "gmailOAuth2": {
          "id": "cyqCGWcggZNMcSOv",
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list"
        },
        "builtInTools": {},
        "options": {}
      },
      "id": "de8d4797-97a2-4c74-90cd-0034e45cc416",
      "name": "OpenAI GPT-4o Mini",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        272,
        128
      ],
      "credentials": {
        "openAiApi": {
          "id": "ICwxUBbatsF2sDvy",
          "name": "OpenAi account"
        }
      }
    }
  ],
  "pinData": {},
  "connections": {
    "Monitor RFP Upload Folder": {
      "main": [
        [
          {
            "node": "Download RFP Document",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download RFP Document": {
      "main": [
        [
          {
            "node": "Upload to Parser",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Parser": {
      "main": [
        [
          {
            "node": "Wait for Parsing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Parsing": {
      "main": [
        [
          {
            "node": "Check Parsing Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Parsing Status": {
      "main": [
        [
          {
            "node": "Route Based on Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route Based on Status": {
      "main": [
        [
          {
            "node": "Extract Parsed Content",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for Parsing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Parsed Content": {
      "main": [
        [
          {
            "node": "Requirement Splitter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Requirement Splitter": {
      "main": [
        [
          {
            "node": "AI Requirement Extractor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Requirement Extractor": {
      "main": [
        [
          {
            "node": "Compliance Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compliance Analyzer": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheets": {
      "main": [
        [
          {
            "node": "Generate Email Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Email Summary": {
      "main": [
        [
          {
            "node": "Send Email via Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI GPT-4o Mini": {
      "ai_languageModel": [
        [
          {
            "node": "AI Requirement Extractor",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "965e8eb6-23ec-4076-9ef9-df1695117f0a",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "3a43da28588548e21903e71cf1dc3ddd65c24bf0c62e7e4b77542ffe87ad79c6"
  },
  "id": "mps6xXNK9f25StYq",
  "tags": []
}